home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1996 #15
/
Monster Media Number 15 (Monster Media)(July 1996).ISO
/
math
/
alged34.zip
/
ALGEDSRC.ZIP
/
ALGMAIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-06
|
13KB
|
373 lines
/*--------------------------------------------------------------------
Alged: Algebra Editor
Copyright (c) 1994,1996 John Henckel
Permission to use, copy, modify, distribute and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies.
Notes;
This was written using the excellent Borland Turbo C++ 3.0 Compiler.
One of the concepts that occurs regularly in this program is the clag.
A clag is a commutative-left-associative-group. For instance,
x+y+z is a clag, but x-y-z is not, because SUB doesn't commute.
And x+(y+z) is not a clag because it is right associative. Clags are
either additive or multiplicative. You can sort, cancel, and combine
elements of a clag. You can move numbers to the bottom (front) or
top (end) of a clag. You can split and join clags by converting
MUL and ADD to/from DIV and SUB. I think most people think in terms
of clags, though they don't call them that.
Notes: The following compiler flags are required:
word alignment off, memory large, signed chars, enums as int.
These are recommended: floating point emulation, fast float, 8086 inst.
If you make any enhancements to this code, please comment them well and
make a note below. I would appreciate it if you send me your enhancements
also! There are a number of utility function you should be aware of,
look at cons, newoper, newnode, freenode, freetree, debug, dumpnode.
I added cons just lately so you may see cases where I should have used
cons but didn't.
Change log:
12/94 JDH first version henckel@vnet.ibm.com
1/95 JDH second version
2/95 JDH vers 2.2 make xlatable, visible comments, tidy up menu
8/95 JDH vers 3.0 complete and uploaded to simtel
2/96 JDH vers 3.2 add palette management, Dutch, other fixes
4/96 JDH vers 3.3 French, focal length control, fill modes
6/96 JDH vers 3.4 autokey, autopick, 3D cylindrical mode, brightness
fix exponential in calcnode, set k=1 (no calc) in poly3,
add combine to expjoin, make factpoly smarter.
*/
#define MAIN
#include "alged.h"
long heapused();
/*--------------------------------------------------------------------
autosrc
This little helper function will set/reset the default source
and target. If src is and equation, it reassigns it to one
side or the other. If tgt is NULL, it assigns it to a var.
The default is 'x' if it exists, else it is the first var found
in src.
*/
node *findvar(node *s, char *name) {
int i; node *t;
if (s->kind==VAR && (!name || !strcmp(name,s->name)))
return s;
for (i=0; i<s->nump; ++i)
if (!!(t=findvar(s->parm[i],name))) return t;
return NULL;
}
void autosrc(int unset) {
static node* oldsrc;
static int fixtgt;
node *tmp;
if (unset!=1) { // SET
oldsrc = NULL;
if (src->kind==EQU) {
oldsrc = src;
if (unset==2 && src->lf->kind==DIV) // this is a hack for polydiv
src = src->lf;
else if (unset==2 && src->rt->kind==DIV)
src = src->rt;
else if (src->rt->kind < src->lf->kind && src->rt->kind != FUN)
src = src->rt;
else
src = src->lf;
}
fixtgt = !tgt;
if (tgt && tgt->kind==VAR && !findvar(src,tgt->name)) {
freetree(tgt);
tgt = NULL;
}
if (!tgt) {
tmp = findvar(src,"x");
if (tmp) tgt = newvar("x");
else {
tmp = findvar(src,NULL);
if (tmp) tgt = deepcopy(tmp);
else tgt = newvar("x"); // if all else fails, set tgt = x
}
}
}
else { // RESET
if (oldsrc) src = oldsrc;
if (fixtgt && tgt) { freetree(tgt); tgt = NULL; }
oldsrc = NULL;
fixtgt = 0;
}
}
/*--------------------------------------------------------------------
main
*/
void main(int argc,char *argv[]) {
int i,x,y,b,done=0,mous=1;
node *tmp,*p;
directvideo = 1; /* don't use bios */
_wscroll = 0; /* disable scrolling */
gettextinfo(&ti);
heapsz = allocmem(32767,NULL); /* find memory available */
heapsz *= 16;
if (heapsz<1) heapsz=400000L; // default
printf("ALGED: Algebra Editor, ver "__DATE__"\n\n");
printf("Copyright (c) 1994,1996 John Henckel\n");
printf("Permission to use, copy, modify, distribute and sell this software\n");
printf("and its documentation for any purpose is hereby granted without fee,\n");
printf("provided that the above copyright notice appear in all copies.\n");
/*-----------------------------------------------------------------
initialize some critical messages to english
*/
msg[1]="parser stack underflow.";
msg[2]="parser r-stack underflow.";
msg[3]="unable to open %s for infix read.";
msg[4]="Unexpected ) or ,";
msg[5]="unable to open %s for postfix read.";
msg[6]="missing function arity %s.";
msg[7]="too few args to %s.";
msg[8]="too many args to %s.";
msg[12]="mouse driver not found in memory.";
msg[13]="option not recognized %d.";
msg[16]="Unable to find menu file '%s'.";
/*-----------------------------------------------------------------
load data files
*/
firf = NULL;
loadfile("alged.1st");
for (i=1; i<argc; ++i)
loadfile(argv[i]);
curf = firf;
if (loadmenu(argv[0])) return;
/*-----------------------------------------------------------------
init mouse
*/
if (init_mouse() != -1) {
printf(msg[12]);
mous=0;
}
/*-----------------------------------------------------------------
main loop
*/
src = curf;
show_menu(); // to establish mheight
while (!done) {
window(2,mheight+1,ti.screenwidth-1,ti.screenheight-1);
textattr(norm);
clrscr();
window(1,1,ti.screenwidth,ti.screenheight); /* full */
display(curf);
show_menu();
_setcursortype(_NOCURSOR);
if (mous) show_mouse();
if (mous) while (!!(b = get_mouse(&x,&y)));
while (!mous || !(b = get_mouse(&x,&y)))
if (kbhit()) {
b = getch();
if (!b && kbhit()) b=300+getch();
break;
}
if (mous) hide_mouse();
_setcursortype(_NORMALCURSOR);
/*-----------------------------------------------------------------
check for keypresses
*/
i=PP0; /* default = do nothing */
if (b==27) break; /* escape */
if (b==332 && src) { /* dump */
putch('\r'); putch('\n');
putch('\n'); putch('\n');
dumpnode(src,1);
do { getch(); } while (kbhit());
continue;
}
else if (b > 7) {
for (i=0; i<numm; ++i)
if (menu[i].hot==b) {
i=menu[i].fid;
break;
}
if (i==numm) continue; /* invalid key */
}
else { /* mouse click */
x=x/8+1; y=y/8+1;
i = selection(x,y);
}
if (i>=0) {
if (i==ESC) break; /* escape */
switch (i) {
case HLP: showhelp(argv[0]); break;
case EQK:
if (src && tgt && src->kind!=EQU && tgt->kind!=EQU) {
tmp = newoper(EQU);
tmp->rt = tgt;
tmp->lf = deepcopy(src);
tgt = tmp;
}
break;
case DIS: if (src) while(distribute(src)); break;
case DI2: if (src) while(distribute_c(src)); break;
case CAL:
if (src) {
while(movenums(src,1,MUL)); /* move up for stretch rule */
while(calcnode(src,0));
while(movenums(src,0,MUL));
while(calcnode(src,0)); // alright, this is a hack for exp.
} break;
case COD:
if (src)
if (src->kind==DIV) while (distribute2(src));
else while (comdeno(src));
break;
case SIM: if (src) simplify(src); break;
case SI2: if (src) simplify2(src,1); break;
case ASS: if (src) associate(src); break;
case PCO: if (src) { autosrc(0); polycoef(tgt,src);} break;
case RAT: if (src) ration(src); break;
case EXX: if (src) while (exexpand(src)); break;
case EXJ: if (src) {
while (combine(src));
while (expjoin(src)); } break;
case SBS: if (src && tgt && tgt->kind==EQU) substitution(src); break;
case QUA: if (src) { autosrc(0); quadratic(tgt,src); autosrc(1);} break;
case FAP: if (src) { autosrc(0); factrpoly(tgt,src); autosrc(1);} break;
case PRI: if (src) primefact(src); break;
case CUB: if (src) { autosrc(0); cubic(tgt,src); autosrc(1);} break;
case GRF: if (src) graph(tgt,src); break;
case XE0: if (src) cross_eq(src,0); break;
case XE1: if (src) cross_eq(src,1); break;
case P2T: src=curf; break;
case P2L: if (src && src->nump>0) src = src->lf; break;
case P2R: if (src && src->nump>1) src = src->rt; break;
case P2K:
if (src) { /* copy pick to key */
p = deepcopy(src);
if (tgt) freetree(tgt);
tgt = p;
} break;
case PLY:
if (src) {
autosrc(2);
if (src->kind==DIV) {
tmp = polydiv(tgt,src->lf,src->rt);
if (tmp) movenode(src,tmp);
while (calcnode(src,1)); /* rmv 0+x and 0*x */
}
autosrc(1);
}
break;
case PPR: panx -= 10; break;
case PP0: panx = 0; break;
case PPL: panx += 10; break;
case CH8: ch8=1-ch8;
if (ch8) {
hline = 196; vline = 179;
urc = 191; llc = 192;
lrc = 217; ulc = 218;
strcpy(piname,msg[33]);
}
else {
hline = '-'; vline = '|';
urc = '\\'; llc = '\\';
lrc = '/'; ulc = '/';
strcpy(piname,msg[32]);
}
clrscr();
break;
case WRI: writefile(keyin(msg[24])); break; /* infix */
case LOD:
loadfile(keyin(msg[25]));
src = curf;
break;
case SAV: savefile(keyin(msg[26])); break; /* postfix only */
case CLR:
while (firf) {
tmp = firf;
firf = firf->next;
freetree(tmp);
} curf = src = NULL;
break;
case ADZ: insertkey(ADD); break;
case SUZ: insertkey(SUB); break;
case MUZ: insertkey(MUL); break;
case DIZ: insertkey(DIV); break;
case EXZ: insertkey(EXP); break;
case DEK: if (tgt) freetree(tgt); tgt=NULL; break;
case DEL:
tmp = curf;
if (!curf) break;
if (curf==firf) curf = firf = firf->next;
else curf = prevnode(curf)->next = curf->next;
freetree(tmp);
break;
case INK:
if (!tgt) break;
tgt->next = curf;
if (curf==firf) curf=firf=tgt;
else {
curf = prevnode(curf);
curf->next = tgt;
curf = tgt;
}
src = curf;
tgt = deepcopy(tgt);
break;
case ENT:
window(1,ti.screenheight-4,ti.screenwidth-1,ti.screenheight-1);
textattr(norm);
clrscr();
if (postfix) cputs(msg[30]); else cputs(msg[31]); putch('\r');
if (tgt) freetree(tgt);
if (postfix) tgt = load("con");
else tgt = loadinfix("con");
window(1,1,ti.screenwidth,ti.screenheight);
break;
case NXT:
if (curf) curf = curf->next;
if (!curf) curf = firf;
src = curf;
break;
case PRV:
if (curf==firf) curf = lastnode(curf);
else curf = prevnode(curf);
src = curf;
break;
default:
printf(msg[13],i); pause;
}
}
else { /* not a menu selection */
tmp = curf;
p = NULL;
for (i=0; i<numsee && tmp; ++i) {
if (!!(p=find_node(tmp,x,y))) break;
tmp = tmp->next;
}
if (!p && tgt)
p = find_node(tgt,x,y);
if (b==1) /* LMB */
src = p;
else if (p) { /* RMB on an expression */
p = deepcopy(p);
if (tgt) freetree(tgt);
tgt = p;
}
else { /* RMB on nothing */
if (tgt) freetree(tgt);
tgt=NULL;
}
}
}
textattr(7);
clrscr();
}